/**
 * 客户端控制器
 * 处理客户端信息的上报和查询
 */
const db = require('../config/database');
const logger = require('../config/logger');

/**
 * 上报客户端信息（无需认证，客户端启动即可上报）
 */
exports.reportClientInfo = async (req, res) => {
  try {
    const clientInfo = req.body;

    // 验证必填字段
    if (!clientInfo.clientId) {
      return res.status(400).json({
        success: false,
        message: '缺少客户端ID'
      });
    }

    // 准备数据
    const data = {
      client_id: clientInfo.clientId,
      // 用户ID从客户端传入，如果未登录则为null
      user_id: clientInfo.userId || null,
      
      // 基本信息
      hostname: clientInfo.hostname || null,
      platform: clientInfo.platform || null,
      os_type: clientInfo.osType || null,
      os_release: clientInfo.osRelease || null,
      arch: clientInfo.arch || null,
      
      // 网络信息
      ip_address: req.ip || null,
      mac_addresses: clientInfo.network?.macAddresses ? JSON.stringify(clientInfo.network.macAddresses) : null,
      
      // CPU信息
      cpu_model: clientInfo.cpu?.model || null,
      cpu_cores: clientInfo.cpu?.cores || null,
      cpu_usage: clientInfo.cpu?.usage || null,
      
      // 内存信息
      total_memory: clientInfo.memory?.total || null,
      free_memory: clientInfo.memory?.free || null,
      memory_usage: clientInfo.memory?.usage || null,
      
      // 磁盘信息
      disk_info: clientInfo.disk ? JSON.stringify(clientInfo.disk) : null,
      
      // 网络流量
      network_rx: clientInfo.network?.rx || 0,
      network_tx: clientInfo.network?.tx || 0,
      
      // 状态信息
      is_online: 1
      // 注意：不在这里设置时间，让数据库的NOW()函数自动生成
    };

    // 检查客户端是否已存在
    const [existing] = await db.query(
      'SELECT id FROM clients WHERE client_id = ?',
      [data.client_id]
    );

    if (existing.length > 0) {
      // 更新现有记录（使用NOW()函数确保时区正确）
      await db.query(
        `UPDATE clients SET
          user_id = ?,
          hostname = ?,
          platform = ?,
          os_type = ?,
          os_release = ?,
          arch = ?,
          ip_address = ?,
          mac_addresses = ?,
          cpu_model = ?,
          cpu_cores = ?,
          cpu_usage = ?,
          total_memory = ?,
          free_memory = ?,
          memory_usage = ?,
          disk_info = ?,
          network_rx = ?,
          network_tx = ?,
          is_online = 1,
          last_heartbeat = NOW(),
          last_report_at = NOW(),
          updated_at = NOW()
        WHERE client_id = ?`,
        [
          data.user_id,
          data.hostname,
          data.platform,
          data.os_type,
          data.os_release,
          data.arch,
          data.ip_address,
          data.mac_addresses,
          data.cpu_model,
          data.cpu_cores,
          data.cpu_usage,
          data.total_memory,
          data.free_memory,
          data.memory_usage,
          data.disk_info,
          data.network_rx,
          data.network_tx,
          data.client_id
        ]
      );
      
      logger.info(`客户端信息已更新: ${data.client_id}`);
    } else {
      // 插入新记录
      await db.query(
        `INSERT INTO clients (
          client_id, user_id, hostname, platform, os_type, os_release, arch,
          ip_address, mac_addresses, cpu_model, cpu_cores, cpu_usage,
          total_memory, free_memory, memory_usage, disk_info,
          network_rx, network_tx, is_online, last_heartbeat, last_report_at
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, NOW(), NOW())`,
        [
          data.client_id,
          data.user_id,
          data.hostname,
          data.platform,
          data.os_type,
          data.os_release,
          data.arch,
          data.ip_address,
          data.mac_addresses,
          data.cpu_model,
          data.cpu_cores,
          data.cpu_usage,
          data.total_memory,
          data.free_memory,
          data.memory_usage,
          data.disk_info,
          data.network_rx,
          data.network_tx
        ]
      );
      
      logger.info(`新客户端已注册: ${data.client_id}`);
    }

    res.json({
      success: true,
      message: '客户端信息上报成功'
    });
  } catch (error) {
    logger.error('上报客户端信息失败:', error);
    res.status(500).json({
      success: false,
      message: '上报客户端信息失败'
    });
  }
};

/**
 * 设置客户端为离线状态（客户端主动通知）
 */
exports.setClientOffline = async (req, res) => {
  try {
    const { clientId } = req.body;

    if (!clientId) {
      return res.status(400).json({
        success: false,
        message: '缺少客户端ID'
      });
    }

    // 更新客户端状态为离线
    const [result] = await db.query(
      'UPDATE clients SET is_online = 0 WHERE client_id = ?',
      [clientId]
    );

    if (result.affectedRows > 0) {
      logger.info(`✅ 客户端 ${clientId} 已主动下线`);
    } else {
      logger.warn(`⚠️  客户端 ${clientId} 不存在或已离线`);
    }

    res.json({
      success: true,
      message: '离线状态已更新'
    });
  } catch (error) {
    logger.error('设置客户端离线状态失败:', error);
    res.status(500).json({
      success: false,
      message: '设置离线状态失败'
    });
  }
};

/**
 * 获取客户端列表
 */
exports.getClientList = async (req, res) => {
  try {
    const { page = 1, pageSize = 20, online, platform, search } = req.query;
    const offset = (page - 1) * pageSize;

    logger.info(`获取客户端列表请求 - page: ${page}, pageSize: ${pageSize}, online: ${online}, platform: ${platform}, search: ${search}`);

    // 🔥 自动更新离线状态（超过30秒未上报的客户端标记为离线）
    await db.query(
      `UPDATE clients 
       SET is_online = 0 
       WHERE last_heartbeat < DATE_SUB(NOW(), INTERVAL 30 SECOND) 
       AND is_online = 1`
    );

    // 构建查询条件
    let whereClauses = [];
    let params = [];

    if (online !== undefined && online !== '') {
      whereClauses.push('c.is_online = ?');
      params.push(parseInt(online));
    }

    if (platform) {
      whereClauses.push('c.platform = ?');
      params.push(platform);
    }

    if (search) {
      whereClauses.push('(c.client_id LIKE ? OR c.hostname LIKE ? OR c.ip_address LIKE ? OR u.username LIKE ?)');
      const searchPattern = `%${search}%`;
      params.push(searchPattern, searchPattern, searchPattern, searchPattern);
    }

    const whereClause = whereClauses.length > 0 ? 'WHERE ' + whereClauses.join(' AND ') : '';

    // 查询总数
    const [countResult] = await db.query(
      `SELECT COUNT(*) as total
       FROM clients c
       LEFT JOIN users u ON c.user_id = u.id
       ${whereClause}`,
      params
    );
    const total = countResult[0].total;

    logger.info(`客户端总数: ${total}`);

    // 查询列表
    const [clients] = await db.query(
      `SELECT 
        c.*,
        u.username,
        u.nickname,
        UNIX_TIMESTAMP(c.last_heartbeat) * 1000 as last_heartbeat_ts,
        TIMESTAMPDIFF(SECOND, c.last_heartbeat, NOW()) as seconds_since_heartbeat
       FROM clients c
       LEFT JOIN users u ON c.user_id = u.id
       ${whereClause}
       ORDER BY c.is_online DESC, c.last_heartbeat DESC
       LIMIT ? OFFSET ?`,
      [...params, parseInt(pageSize), offset]
    );

    logger.info(`查询到 ${clients.length} 条客户端记录`);

    // 处理JSON字段，增加错误处理
    const processedClients = clients.map(client => {
      try {
        return {
          ...client,
          mac_addresses: client.mac_addresses ? 
            (typeof client.mac_addresses === 'string' ? JSON.parse(client.mac_addresses) : client.mac_addresses) : [],
          disk_info: client.disk_info ? 
            (typeof client.disk_info === 'string' ? JSON.parse(client.disk_info) : client.disk_info) : []
        };
      } catch (parseError) {
        logger.error(`解析客户端 ${client.client_id} 的JSON字段失败:`, parseError);
        return {
          ...client,
          mac_addresses: [],
          disk_info: []
        };
      }
    });

    res.json({
      success: true,
      data: {
        clients: processedClients,
        pagination: {
          page: parseInt(page),
          pageSize: parseInt(pageSize),
          total,
          totalPages: Math.ceil(total / pageSize)
        }
      }
    });
  } catch (error) {
    logger.error('获取客户端列表失败:', error);
    logger.error('错误堆栈:', error.stack);
    res.status(500).json({
      success: false,
      message: '获取客户端列表失败: ' + error.message
    });
  }
};

/**
 * 获取客户端详情
 */
exports.getClientDetail = async (req, res) => {
  try {
    const { clientId } = req.params;

    const [clients] = await db.query(
      `SELECT 
        c.*,
        u.username,
        u.nickname,
        u.email,
        UNIX_TIMESTAMP(c.last_heartbeat) * 1000 as last_heartbeat_ts,
        TIMESTAMPDIFF(SECOND, c.last_heartbeat, NOW()) as seconds_since_heartbeat
       FROM clients c
       LEFT JOIN users u ON c.user_id = u.id
       WHERE c.client_id = ?`,
      [clientId]
    );

    if (clients.length === 0) {
      return res.status(404).json({
        success: false,
        message: '客户端不存在'
      });
    }

    const client = clients[0];
    
    // 处理JSON字段
    client.mac_addresses = client.mac_addresses ? JSON.parse(client.mac_addresses) : [];
    client.disk_info = client.disk_info ? JSON.parse(client.disk_info) : [];

    res.json({
      success: true,
      data: client
    });
  } catch (error) {
    logger.error('获取客户端详情失败:', error);
    res.status(500).json({
      success: false,
      message: '获取客户端详情失败'
    });
  }
};

/**
 * 获取客户端统计信息
 */
exports.getClientStats = async (req, res) => {
  try {
    logger.info('开始获取客户端统计信息...');

    // 🔥 自动更新离线状态（超过30秒未上报的客户端标记为离线）
    await db.query(
      `UPDATE clients 
       SET is_online = 0 
       WHERE last_heartbeat < DATE_SUB(NOW(), INTERVAL 30 SECOND) 
       AND is_online = 1`
    );

    // 总数统计
    const [totalResult] = await db.query('SELECT COUNT(*) as total FROM clients');
    const total = totalResult[0].total;
    logger.info(`客户端总数: ${total}`);

    // 在线数统计
    const [onlineResult] = await db.query('SELECT COUNT(*) as online FROM clients WHERE is_online = 1');
    const online = onlineResult[0].online;
    logger.info(`在线客户端: ${online}`);

    // 离线数统计
    const offline = total - online;

    // 平台统计
    const [platformResult] = await db.query(
      `SELECT platform, COUNT(*) as count
       FROM clients
       GROUP BY platform
       ORDER BY count DESC`
    );

    // 最近活跃
    const [recentActive] = await db.query(
      `SELECT COUNT(*) as count
       FROM clients
       WHERE last_heartbeat >= DATE_SUB(NOW(), INTERVAL 1 HOUR)`
    );

    const stats = {
      total,
      online,
      offline,
      onlineRate: total > 0 ? ((online / total) * 100).toFixed(2) : 0,
      platforms: platformResult,
      recentActive: recentActive[0].count
    };

    logger.info('客户端统计信息获取成功:', JSON.stringify(stats));

    res.json({
      success: true,
      data: stats
    });
  } catch (error) {
    logger.error('获取客户端统计失败:', error);
    logger.error('错误堆栈:', error.stack);
    logger.error('错误详情:', {
      name: error.name,
      message: error.message,
      code: error.code,
      errno: error.errno,
      sqlMessage: error.sqlMessage
    });
    res.status(500).json({
      success: false,
      message: '获取客户端统计失败: ' + error.message
    });
  }
};

/**
 * 删除客户端记录
 */
exports.deleteClient = async (req, res) => {
  try {
    const { clientId } = req.params;

    const [result] = await db.query(
      'DELETE FROM clients WHERE client_id = ?',
      [clientId]
    );

    if (result.affectedRows === 0) {
      return res.status(404).json({
        success: false,
        message: '客户端不存在'
      });
    }

    logger.info(`客户端已删除: ${clientId}`);

    res.json({
      success: true,
      message: '删除成功'
    });
  } catch (error) {
    logger.error('删除客户端失败:', error);
    res.status(500).json({
      success: false,
      message: '删除客户端失败'
    });
  }
};

/**
 * 获取在线客户端列表（用于下发任务）
 */
exports.getOnlineClients = async (req, res) => {
  try {
    // 获取socketManager实例
    const socketManager = req.app.get('socketManager');
    if (!socketManager) {
      return res.status(500).json({
        success: false,
        message: 'WebSocket服务未初始化'
      });
    }

    // 从数据库直接查询在线客户端（is_online=1）
    const [clients] = await db.query(
      `SELECT 
        c.client_id,
        c.hostname,
        c.platform,
        c.os_type,
        c.ip_address,
        c.user_id,
        c.last_heartbeat,
        u.username,
        u.nickname
       FROM clients c
       LEFT JOIN users u ON c.user_id = u.id
       WHERE c.is_online = 1
       ORDER BY c.last_heartbeat DESC`
    );

    // 检查这些客户端是否真的有 WebSocket 连接
    const socketClients = socketManager.getOnlineClients();
    const socketClientIds = new Set(socketClients.map(c => c.clientId));

    // 标记哪些客户端有 WebSocket 连接
    const result = clients.map(client => ({
      ...client,
      hasWebSocket: socketClientIds.has(client.client_id)
    }));

    logger.info(`在线客户端数量: ${clients.length}, 其中有WebSocket连接: ${result.filter(c => c.hasWebSocket).length}`);

    res.json({
      success: true,
      data: result
    });
  } catch (error) {
    logger.error('获取在线客户端列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取在线客户端列表失败'
    });
  }
};

/**
 * 获取客户端目录列表
 */
exports.getClientDirectory = async (req, res) => {
  try {
    const { clientId } = req.params;
    const { path = '/' } = req.query;

    // 获取socketManager实例
    const socketManager = req.app.get('socketManager');
    if (!socketManager) {
      return res.status(500).json({
        success: false,
        message: 'WebSocket服务未初始化'
      });
    }

    // 请求客户端目录
    const directory = await socketManager.requestClientDirectory(clientId, path);

    res.json({
      success: true,
      data: directory
    });
  } catch (error) {
    logger.error('获取客户端目录失败:', error);
    res.status(500).json({
      success: false,
      message: error.message || '获取客户端目录失败'
    });
  }
};

/**
 * 下发传输任务到客户端
 */
exports.dispatchTask = async (req, res) => {
  try {
    const {
      clientId,
      type,        // 'upload' | 'download'
      sourcePath,  // 客户端路径（上传时）或服务器路径（下载时）
      targetPath,  // 服务器路径（上传时）或客户端路径（下载时）
      files        // 文件列表 [{name, size, isDirectory}]
    } = req.body;

    // 验证必填字段
    if (!clientId || !type || !sourcePath || !targetPath || !files || files.length === 0) {
      return res.status(400).json({
        success: false,
        message: '缺少必填参数'
      });
    }

    // 验证任务类型
    if (!['upload', 'download'].includes(type)) {
      return res.status(400).json({
        success: false,
        message: '无效的任务类型'
      });
    }

    // 获取socketManager实例
    const socketManager = req.app.get('socketManager');
    if (!socketManager) {
      return res.status(500).json({
        success: false,
        message: 'WebSocket服务未初始化'
      });
    }

    // 构建任务配置
    const task = {
      type,
      sourcePath,
      targetPath,
      files,
      timestamp: Date.now()
    };

    // 下发任务到客户端
    const taskId = await socketManager.dispatchTransferTask(clientId, task);

    logger.info(`✅ 传输任务已下发成功: ${taskId}`);

    res.json({
      success: true,
      data: {
        taskId,
        message: '任务已下发到客户端'
      }
    });
  } catch (error) {
    logger.error('下发传输任务失败:', error);
    res.status(500).json({
      success: false,
      message: error.message || '下发传输任务失败'
    });
  }
};
